"""
# Copyright 2009 German Aerospace Center (DLR)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""

import math
from PIL import ImageFont

class PyTagCloud(object):
    """ Class creates a cloud of Words
        it is important that a font is given with its full pathname, otherwise
        no font is used
        
    """

    def __init__(self, canvas=(800, 600), font="C:\Windows\Fonts\ARIAL.TTF", \
                 quantity=None):
        """ Constructor
        """
        self.words = {}
        self.quantity = quantity
        self.canvas = canvas
        self.font = font



    def limit_dict(self, words):
        """ limits the size of the dictionary ordered by occurrences
            
        """
        limited_dict = {}

        val_list = words.values()

        val_list.sort()
        val_list.reverse()
        val_list_cutted = val_list[:self.quantity]

        for item in words.items():
            if item[1] in val_list_cutted:
                limited_dict[item[0]] = item[1]

        return limited_dict
        
        
    def make_cloud(self, steps, words):
        """ The logarithmic Cloud Generating algorithm.
            
            
        """
        list_of_word_tuples = self.limit_dict(words)
        temp_list_of_values = []

        for value in list_of_word_tuples.values():
            temp_list_of_values.append(value)

        max_val = max(temp_list_of_values)
        min_val = min(temp_list_of_values)

        delta_value = float((max_val - min_val)) / steps
        
        new_thresholds = []
        
        for counter in range(steps + 1):
            new_thresholds.append((100 * math.log((min_val + counter * delta_value) + 2), counter))

        results = {}

        for key in list_of_word_tuples:
            font_set_flag = False
    
            for item in new_thresholds[1:int(steps) + 1]:
                if (100 * math.log(list_of_word_tuples[key] + 2)) <= item[0] and not font_set_flag:
                    results[key] = item[1] + 5
                    font_set_flag = True
        return results



    def get_coords(self, words, steps = 6):
        """ creates a list of dictionaries with content, fontsize, 
            canvas_size_x and y locations, height, and width. 
            
        """

        coords = []
        cloud_dict = self.limit_dict(words)
        cloud_dict = self.make_cloud(steps, words)
        start_point_x = 0
        start_point_y = 0
        y_appendix = 0
        line_height = 0

        for item in cloud_dict.items():

            item_dict = {"content":item[0], "fontsize":item[1],
                         "x":0, "y":0,
                         "h":0, "w":0}
            try:
                font = ImageFont.truetype(self.font, item[1])
                size = font.getsize(item[0])
            except IOError:
                print "Sorry, font not found"
                break 
            
            if size[1] > line_height:
                line_height = size[1]

            if (start_point_x + size[0] + 10) > self.canvas[0]:
                start_point_x = 0
                y_appendix = y_appendix + line_height

            if (y_appendix + size[1]) > self.canvas[1]:
                break

            start_point_x = start_point_x + size[0]

            item_dict["x"] = start_point_x
            item_dict["y"] = start_point_y + y_appendix

            item_dict["h"] = line_height
            item_dict["w"] = size[0]

            coords.append(item_dict)

        return coords


